#include "window.h"

class WindowPrivate{
public:
    WindowPrivate(){};
    ~WindowPrivate(){}

    QTimeLine *timeLine;
    bool popupShown;
    QGraphicsItem *currentPopup;
};

Window::Window(QGraphicsItem * parent, Qt::WindowFlags wFlags) :
        QGraphicsProxyWidget(parent, wFlags), O_PRIVATE_CREATE(Window)
{
    O_D(Window)
    d->timeLine = new QTimeLine(500, this);
    d->timeLine->setCurveShape(QTimeLine::EaseInOutCurve);
    d->timeLine->setFrameRange(0, 74);

   // connect(d->timeLine, SIGNAL(valueChanged(qreal)), this, SLOT(updateStep(qreal)));
   // connect(d->timeLine, SIGNAL(stateChanged(QTimeLine::State)), this, SLOT(stateChanged(QTimeLine::State)));
}

Window::~Window()
{
    O_PRIVATE_DELETE;
}



QRectF Window::boundingRect() const
{
    return QGraphicsProxyWidget::boundingRect().adjusted(0, 0, 10, 10);
}

void Window::paintWindowFrame(QPainter *painter, const QStyleOptionGraphicsItem *option,
                              QWidget *widget)
{
//    const QColor color(0, 0, 0, 64);

//    O_D(Window)
//    QRectF r = windowFrameRect();

//    QLinearGradient gradient(QPointF(0, 0), r.bottomRight());
//    gradient.setColorAt(0.4, Qt::white);
//    gradient.setColorAt(4, Qt::transparent);


//    QRectF right(r.right(), r.top() + 10, 10, r.height() - 10);
//    QRectF bottom(r.left() + 10, r.bottom(), r.width(), 10);
//    bool intersectsRight = right.intersects(option->exposedRect);
//    bool intersectsBottom = bottom.intersects(option->exposedRect);
//    if (intersectsRight && intersectsBottom) {
//        QPainterPath path;
//        path.addRect(right);
//        path.addRect(bottom);
//        painter->setPen(Qt::NoPen);

//        painter->setBrush(gradient);
//        painter->drawPath(path);
//    } else if (intersectsBottom) {
//        painter->fillRect(bottom, gradient);
//    } else if (intersectsRight) {
//        painter->fillRect(right, gradient);
//    }

    QGraphicsProxyWidget::paintWindowFrame(painter, option, widget);
}

void Window::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
{
    O_D(Window)
    QGraphicsProxyWidget::hoverEnterEvent(event);
    scene()->setActiveWindow(this);
    if (d->timeLine->currentValue() != 1)
        zoomIn();
}

void Window::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
{
    O_D(Window)
    QGraphicsProxyWidget::hoverLeaveEvent(event);
    if (!d->popupShown && (d->timeLine->direction() != QTimeLine::Backward || d->timeLine->currentValue() != 0))
        zoomOut();
}

bool Window::sceneEventFilter(QGraphicsItem *watched, QEvent *event)
{
    O_D(Window)
    if (watched->isWindow() && (event->type() == QEvent::UngrabMouse || event->type() == QEvent::GrabMouse)) {
        d->popupShown = watched->isVisible();
        if (!d->popupShown && !isUnderMouse())
            zoomOut();
    }
    return QGraphicsProxyWidget::sceneEventFilter(watched, event);
}

QVariant Window::itemChange(GraphicsItemChange change, const QVariant &value)
{
    O_D(Window)
    if (change == ItemChildAddedChange || change == ItemChildRemovedChange) {
        if (change == ItemChildAddedChange) {
            d->currentPopup = qVariantValue<QGraphicsItem *>(value);
            d->currentPopup->setCacheMode(ItemCoordinateCache);
            if (scene())
                d->currentPopup->installSceneEventFilter(this);
        } else if (scene()) {
            d->currentPopup->removeSceneEventFilter(this);
            d->currentPopup = 0;
        }
    } else if (d->currentPopup && change == ItemSceneHasChanged) {
        d->currentPopup->installSceneEventFilter(this);
    }
    return QGraphicsProxyWidget::itemChange(change, value);
}

void Window::updateStep(qreal step)
{
    O_D(Window)
    QRectF r = boundingRect();
    qDebug() << 74 * step;
    setOpacity(step);
//    setTransform(QTransform()
//                 //.translate(r.width() / 2, r.height() / 2)
//                 //.rotate(step * 30, Qt::XAxis)
//                // .rotate(step * 10, Qt::YAxis)
//                // .rotate(step * 5, Qt::ZAxis)
//                 //.scale(1 + 0.3 * step, 1 + 0.3 * step)
//                 .translate(0, 74 * step));
}

void Window::stateChanged(QTimeLine::State state)
{
    O_D(Window)
    if (state == QTimeLine::Running) {
        if (d->timeLine->direction() == QTimeLine::Forward)
            setCacheMode(ItemCoordinateCache);
    } else if (state == QTimeLine::NotRunning) {
        if (d->timeLine->direction() == QTimeLine::Backward)
            setCacheMode(DeviceCoordinateCache);
    }
}

void Window::zoomIn()
{
    O_D(Window)
    if (d->timeLine->direction() != QTimeLine::Forward)
        d->timeLine->setDirection(QTimeLine::Forward);
    if (d->timeLine->state() == QTimeLine::NotRunning)
        d->timeLine->start();
}

void Window::zoomOut()
{
    O_D(Window)
    if (d->timeLine->direction() != QTimeLine::Backward)
        d->timeLine->setDirection(QTimeLine::Backward);
    if (d->timeLine->state() == QTimeLine::NotRunning)
        d->timeLine->start();
}
